#include <iostream>
#include <map>
#include <string>

using namespace std;

// int main()
// {
//     // 1. 解包数组
//     int arr[2] = {1, 2};
//     auto [x, y] = arr; // x = 1, y = 2

//     cout << x << endl;
//     cout << y << endl;

//     // 需要注意的是结构化绑定是将arr中的值拷贝给x和y
//     // 也就是说x和y的改变，不影响数组中的值
//     x++;
//     cout << arr[0] << endl;
//     // 这里加引用，就可以做到xx和yy是数组中对应值的别名
//     auto &[xx, yy] = arr;
//     xx++;
//     cout << arr[0] << endl;

//     // 2. 解包元组(std::tuple)
//     std::tuple<int, double, std::string> t(1, 2.3, "hello");
//     auto [a1, b1, c1] = t;
//     auto &[a2, b2, c2] = t;
//     auto &&[a3, b3, c3] = move(t);
//     // auto &[a4, b4] = std::make_tuple(1, 2); // 编译报错
//     auto &&[a5, b5] = std::make_tuple(1, 2);

//     // 3.解包结构体/类
//     struct Point
//     {
//         void func()
//         {
//             auto [x1, y1] = *this; // x1=1.1, y1=2.2
//             cout << x1 << endl;
//             cout << y1 << endl;
//         }
//     // private:
//         double x;
//         double y;
//     };

//     // 如果成员变量是私有的，则无法做结构化绑定
//     Point p{1.1, 2.2};
//     auto [x1, y1] = p; // x1=1.1, y1=2.2
//     cout << x1 << endl;
//     cout << y1 << endl;

//     // 结构化绑定不支持嵌套绑定 auto [[ mm1, mm2 ], nn1] = std::make_tuple(p, 1); // 报错
//     auto [m1, n1] = std::make_tuple(p, 1);
//     // 实践使用场景：范围for叠加结构化绑定使用遍历map
//     std::map<std::string, int> m = {{"xxxx", 1}, {"yyyy", 2}};
//     for (const auto& [key, value] : m)
//     {
//         std::cout << key << ": " << value << "\n";
//     }

//     return 0;
// }

// 不是.cpp里面是同一个地址的值，而不是副本
// inline const int cacheSize = 4 * 1024;

// class Widget
// {
// public:
//     static std::string name;      // 声明
//     static const int version = 1; // 仅对整型static const允许类内定义初始化
// };

// std::string Widget::name = "张三"; // 定义初始化

// class Widget
// {
// public:
//     inline static std::string name = "张三";  // 定义初始化
//     static const int version = 1;             // 仅对整型static const允许类内定义初始化
// };

// #include <iostream>
// #include <map>
// #include <string>

// // 示例1: if语句中的初始化
// void ifWithInit()
// {
//     std::map<std::string, int> m = {{"Alice", 25}, {"Bob", 30}};
//     // 在if条件中初始化变量
//     if (auto it = m.find("Alice"); it != m.end())
//     {
//         std::cout << "Found Alice, age: " << it->second << std::endl;
//     }
//     else
//     {
//         std::cout << "Alice not found" << std::endl;
//     }

//     // 变量it的作用域仅限于if-else块
// }

// int checkValue(int v)
// {
//     return v % 2;
// }

// // 示例2 : switch语句中的初始化 
// void switchWithInit(int value)
// {
//     // 在switch条件中初始化变量
//     switch (auto status = checkValue(value); status)
//     {
//     case 0:
//         std::cout << "Status is zero" << std::endl;
//         break;
//     case 1:
//         std::cout << "Status is one" << std::endl;
//         break;
//     default:
//         std::cout << "Unknown status: " << status << std::endl;
//     }
//     // status的作用域仅限于switch块
// }

// int main()
// {
//     ifWithInit();
//     switchWithInit(42);

//     return 0;
// }

//struct Noisy
//{
//    Noisy() { std::cout << "constructed at " << this << '\n'; }
//    Noisy(const Noisy&) { std::cout << "copy-constructed\n"; }
//    Noisy(Noisy&&) { std::cout << "move-constructed\n"; }
//    ~Noisy() { std::cout << "destructed at " << this << '\n'; }
//};
//
//Noisy f()
//{
//    Noisy v = Noisy(); // (until C++17) copy elision initializing v from a temporary;
//                       //               the move constructor may be called
//                       // (since C++17) "guaranteed copy elision"
//    //return Noisy(); // copy elision ("NRVO") from v to the result object;
//              // the move constructor may be called
//
//    return v;
//}
//
//void g(Noisy arg)
//{
//    std::cout << "&arg = " << &arg << '\n';
//}
//
//int main()
//{
//    Noisy ret = f(); // (until C++17) copy elision initializing v from the result of f()
//                   // (since C++17) "guaranteed copy elision"
//
//    std::cout << "&ret = " << &ret << '\n' << '\n';
//
//    g(f()); // (until C++17) copy elision initializing arg from the result of f()
//            // (since C++17) "guaranteed copy elision"
//}

//struct NonMoveable {
//	NonMoveable() = default;
//	NonMoveable(const NonMoveable&) = delete; // 禁止拷贝
//	NonMoveable(NonMoveable&&) = delete; // 禁止移动
//};
//
//NonMoveable make() {
//	return NonMoveable(); // ❌ 在 C++14 中编译错误！
//	// 因为语言逻辑上要求调用已删除的移动构造函数
//}
//
//int main() {
//	NonMoveable nm = make(); // ❌ 同样错误
//}

//#include <iostream>
//#include <type_traits>
//
//// 示例1: 基本用法
//template<typename T>
//auto printTypeInfo(const T& value) {
//	if constexpr (std::is_integral_v<T>) {
//		std::cout << value << " is an integral type" << std::endl;
//	}
//	else if constexpr (std::is_floating_point_v<T>) {
//		std::cout << value << " is a floating point type" << std::endl;
//	}
//	else if constexpr (std::is_pointer_v<T>) {
//		std::cout << "Pointer to " << *value << std::endl;
//	}
//	else {
//		std::cout << value << " is some other type" << std::endl;
//	}
//}
//
////void printArgs()
////{}
//
//// 示例2: 在模板元编程中使用
//template<typename T, typename... Args>
//void printArgs(T&& arg, Args&&... args) {
//	std::cout << arg;
//	if constexpr (sizeof...(args) > 0) {
//		std::cout << ", ";
//		printArgs(std::forward<Args>(args)...);
//	}
//	else {
//		std::cout << std::endl;
//	}
//}
//
//// 示例3: 类型分发
//template<typename T>
//void process(T value) {
//	if constexpr (std::is_same_v<T, int>) {
//			std::cout << "Processing int: " << value * 2 << std::endl;
//	}
//	else if constexpr (std::is_same_v<T, std::string>) {
//		std::cout << "Processing string: " << value.length() << " chars" <<
//			std::endl;
//	}
//	else {
//		static_assert(std::is_same_v<T, int> || std::is_same_v<T, std::string>,
//			"Unsupported type");
//	}
//}
//
//int main() {
//	printTypeInfo(42);
//	printTypeInfo(3.14);
//	int x = 10;
//	printTypeInfo(&x);
//	printTypeInfo("hello");
//
//	printArgs(1, 2.5, "three", '4');
//
//	process(100);
//	process(std::string("test"));
//	process(3.14); // 编译错误，因为static_assert
//}

//#include <iostream>
//#include <vector>
//#include <tuple>
//
//#include <array>
//// 示例1: 标准库容器的自动推导
//void containerDeduction() {
//	// C++17之前需要指定模板参数
//	std::vector<int> v1 = { 1, 2, 3 };
//	// C++17可以自动推导
//	std::vector v2 = { 4, 5, 6 }; // 推导为vector<int>
//	//std::vector v3{ std::string("hello"), std::string("world") };
//	std::vector v3{"hello", "world"}; // 推导为vector<const char*>
//	std::vector v4(10, 1.1);
//	std::vector v5(v1.begin(), v1.end());
//	//std::vector v6; // 报错
//	std::less l;
//
//	std::cout << typeid(v2).name() << std::endl;
//	std::cout << typeid(v3).name() << std::endl;
//	std::cout << typeid(v4).name() << std::endl;
//	std::cout << typeid(v5).name() << std::endl;
//	// std::cout << typeid(v6).name() << std::endl;
//
//	// 类似地适用于其他容器
//	std::array a = { 1, 2, 3 }; // 推导为array<int, 3>
//	std::pair p(1, 2.0); // 推导为pair<int, double>
//	std::tuple t(1, 2.0, "three"); // 推导为tuple<int, double, const char*>
//	std::cout << "v2 size: " << v2.size() << std::endl;
//	std::cout << "a size: " << a.size() << std::endl;
//	std::cout << "p first: " << p.first << ", second: " << p.second << std::endl;
//}
//
//int main()
//{
//	containerDeduction();
//}

//#include <iostream>
//#include <string>
//#include <string_view>
//#include <array>
//#include <typeinfo>
//
//template<auto Value>
//void printValue() {
//	//std::cout << "Value: " << Value << std::endl;
//	std::cout << "Type: " << typeid(Value).name() << std::endl; // 打印类型名（编译器相关）
//	std::cout << "---" << std::endl;
//}
//
//const char arr[] = "hello";
//
//// 一个简单的字面量类类型
//struct Point {
//	int x;
//	int y;
//	// 编译器会为我们生成一个隐式的 constexpr 构造函数
//	// 析构函数也是隐式 constexpr 的
//};
//
////template<int... Values>
////struct ValueList
////{
////}; // 一个编译期的值列表
//
//template<auto... Values>
//struct ValueList
//{
//	ValueList()
//	{
//		/*(std::cout << ... << Values);
//		std::cout << '\n';*/
//
//		// 逗号折叠表达式
//		((std::cout << Values << ' '), ...);
//		std::cout << '\n';
//	}
//
//}; // 一个编译期的值列表
//
//int main() {
//	printValue<42>(); // auto 被推导为 int
//	printValue<3.14>(); // auto 被推导为 double C++20开始才支持
//	printValue<'A'>(); // auto 被推导为 char
//	printValue<true>(); // auto 被推导为 bool
//	printValue<nullptr>(); // auto 被推导为 nullptr_t
//
//	//printValue<"hello">(); // 错误：字符串字面量不能作为非类型模板参数
//	//std::cout << "Type: " << typeid("hello").name() << std::endl;
//	printValue<arr>(); // auto 被推导为 const char*
//
//	// C++20开始支持字面量类类型作为非类型模板参数
//	printValue < Point{ 10, 20 } > ();
//	constexpr std::array arr{ 1, 2, 3, 4, 5 };
//	printValue<arr>();
//
//	ValueList<1,2,3,4,5> vl1;
//	ValueList<1, 'x', 1.1> vl2;
//
//	// constexpr string str("Hello");
//	// printValue<string("Hello")>(); // 报错
//
//	// printValue<std::string_view("Hello")>();
//}

// 1、一元左折叠
//template<typename... Args>
//bool all(Args... args)
//{
//	return (... && args);
//	// return (((true && true) && true) && false);
//}

// 右折叠
//template<typename... Args>
//bool all(Args... args)
//{
//	return (args && ...);
//	// return (true && (true && (true && false)));
//}
//
//// 2、一元右折叠
//template<typename... Args>
//auto sum(Args... args) {
//	//return (args + ...);
//	// 等价于 return (arg1 + (arg2 + (arg3 + ...)));
//	return (... + args);
//}
//
//int main()
//{
//	std::cout << all(true, true, true, false) << std::endl; // 输出false
//	std::cout << sum(1, 2, 3, 4); // 输出 10
//
//	return 0;
//}

//// 3、二元左折叠
//template<typename... Strings>
//std::string concat_left(Strings... strs) {
//	return (std::string("%%") + ... + strs);
//	// 展开形式：((("%%" + str1) + str2)+ str3)
//}
//
//// 4、二元右折叠，初始值为空字符串
//template<typename... Strings>
//std::string concat_right(Strings... strs) {
//	return (strs + ... + std::string("%%"));
//	// 展开形式：str1 + (str2 + (str3 + "%%"))
//}
//
//// 二元左折叠，不能写成右折叠
//template<typename... Args>
//void print(Args&&... args) {
//	(std::cout << ... << args) << '\n';
//	// 等价于 (((std::cout << arg1) << arg2) << ...) << argN;
//}
//
//// 一个更高级的技巧：使用逗号运算符和lambda来添加分隔符
//template<typename... Args>
//void print_with_separator(Args&&... args) {
//
//	auto print_elem = [](const auto& x) {
//		std::cout << x << " ";
//	};
// 
//	(..., print_elem(args)); // 一元左折叠：
//	// ((print_elem(arg1),print_elem(arg2)), print_elem(arg3))
//
//	std::cout << std::endl;
//}
//
//template<typename T, typename... Args>
//void push_back_vec(std::vector<T>& v, Args&&... args)
//{
//	(v.push_back(std::forward<Args>(args)), ...);
//}
//
//
//int main() {
//	std::cout << concat_left("x", "y", "z") << "\n";
//	std::cout << concat_right("x", "y", "z") << "\n";
//
//	print(1, string("xxxxx"), 2.2);
//
//	print_with_separator(1, string("xxxxx"), 2.2, 3.3);
//
//	std::vector<int> v;
//	push_back_vec(v, 1,2,3,4);
//	for (int i : v)
//		std::cout << i << ' ';
//	std::cout << '\n';
//
//	int a = 0;
//	//int c = (a += 1, a += 2, a += 3);
//	int c = (a += 1, (a += 2, a += 3));
//	cout << c << endl;
//
//	std::cout << '\n';
//}
//
//template<typename... Args>
//bool all(Args... args)
//{
//	return (... || args);
//	// return ((true && true) && true) && false;
//}
//
//template<typename... Args>
//auto sum(Args... args) {
//	//return (args + ...+0);
//	return (args + ... );
//	// 等价于 return (arg1 + (arg2 + (arg3 + ...)));
//}
//
//template<typename... Args>
//void print_with_separator(Args&&... args) {
//
//	auto print_elem = [](const auto& x) {
//		std::cout << x << " ";
//	};
// 
//	(..., print_elem(args)); // 一元左折叠：
//	// ((print_elem(arg1),print_elem(arg2)), print_elem(arg3))
//
//	std::cout << std::endl;
//}

// C++17的简洁嵌套命名空间
//namespace A::B::C {
//	void bar() {
//		std::cout << "New nested namespace style" << std::endl;
//	}
//}
//
//namespace A::B {
//	void qux() {
//		std::cout << "Partially nested namespace" << std::endl;
//	}
//}
//
//// 定义别名
//namespace abc = A::B::C;
//
//int main() {
//	//A::B::C::foo();
//	A::B::C::bar();
//	abc::bar();
//
//	A::B::qux();
//
//	return 0;
//}

//// 示例1: 检查标准库头文件
//#if __has_include(<optional>)
//	#include <optional>
//	#define HAS_OPTIONAL 1
//#else
//	#define HAS_OPTIONAL 0
//#endif
//
//// 示例2: 检查自定义头文件
//#if __has_include("my_header.h")
//	#include "my_header.h"
//	#define HAS_MY_HEADER 1
//#else
//	#define HAS_MY_HEADER 0
//#endif
//
//// 示例3：检查是否支持文件系统相关库
//#if __has_include(<filesystem>)
//	#include <filesystem>
//	namespace fs = std::filesystem;
//#elif __has_include(<experimental/filesystem>)
//	#include <experimental/filesystem>
//	namespace fs = std::experimental::filesystem;
//#else
//	#error "需要 filesystem 支持"
//#endif
//
//#if __has_include(<windows.h>)
//	#include<windows.h>
//#else
//	// #include<xxx.h>
//#endif
//
//int main() {
//	std::cout << "Optional support: " << HAS_OPTIONAL << std::endl;
//	std::cout << "My header support: " << HAS_MY_HEADER << std::endl;
//
//	// 实际使用
//#if HAS_OPTIONAL
//	std::optional<int> opt = 42;
//	std::cout << "Optional value: " << *opt << std::endl;
//#else
//	std::cout << "Optional not available" << std::endl;
//#endif
//
//	return 0;
//}

//#include <iostream>
//#include <vector>
//#include <map>
//#include <optional>
//
//// 结合文档，optional的基本使用
//void test_example1()
//{
//	// 1、定义optional 对象
//	std::optional<int> maybeInt; // 初始为空
//	std::optional<std::string> maybeString = "Hello"; // 初始有值
//	std::optional<double> empty = std::nullopt; // 显式设置为空
//	maybeString = "xxx";
//	if (maybeString)
//	{
//		std::cout << maybeString.value() << std::endl;
//	}
//
//	maybeString = std::nullopt;
//
//	// 3、访问值
//	// 安全访问 - 无值时抛出 std::bad_optional_access
//	try {
//		int value = maybeInt.value();
//	}
//	catch (const std::bad_optional_access& e) {
//		std::cout << e.what() << std::endl;
//	}
//	
//	maybeInt = 1;
//
//	maybeInt = std::nullopt;
//	// 不安全但快速的访问 - 无值时行为未定义
//	//int value1 = *maybeInt;
//
//	// 带默认值的访问
//	int value2 = maybeInt.value_or(2); // 无值时返回2
//	std::cout << value2 << std::endl;
//}
//
//// optional实践中的使用场景
//void test_example2()
//{
//	// 查找一个顶点对应的下标编号
//	std::map<std::string, int> indexMap = { {"张庄",1}, {"王村",2}, {"李家村",3}, {"王家坪",4} };
//	auto findIndex = [&indexMap](const std::string& str)->std::optional<int>
//	{
//		auto it = indexMap.find(str);
//		if (it != indexMap.end())
//		{
//			return it->second;
//		}
//		else
//		{
//			return std::nullopt;
//		}
//	};
//
//	std::string x;
//	std::cin >> x;
//	std::optional<int> index = findIndex(x);
//	if (index)
//	{
//		std::cout << x << "对应的编号为:" << *index << std::endl;
//	}
//	else
//	{
//		std::cout << x << "是非法顶点" << std::endl;
//	}
//
//	std::vector<std::string> v = { "张庄", "李庄", "" };
//	auto access = [&v](int i)-> std::optional<std::string>
//	{
//		if (i < v.size())
//		{
//			return v[i];
//		}
//		else
//		{
//			// 以前的语法这里函数只能用抛异常或者断言方式处理i越界的情况
//			// i越界不能返回""，因为正常数据可能就是"",无法区分
//			std::nullopt;
//		}
//	};
//}
//
//int main()
//{
//	// test_example1();
//	test_example2();
//
//	return 0;
//}

#include <variant>
#include <string>
#include <iostream>
#include <vector>
#include <list>
#include <set>

// 示例1: 定义和赋值
//int main() {
//	// 定义一个 variant，它可以存储一个 int, 一个 double, 或一个 std::string
//	std::variant<int, double, std::string> v = 2.2;
//
//	v = 1;
//	std::cout << v.index() << std::endl;
//	std::cout << v.index() << std::endl;
//
//	v = 1.1;
//	std::cout << v.index() << std::endl;
//
//	v = "xxxxxx";
//	std::cout << v.index() << std::endl;
//
//	v = '$';
//	std::cout << v.index() << std::endl;
//
//	// v = std::pair<int, int>();
//
//	//std::variant<int, double> v = 42;
//	//try {
//	//	std::cout << std::get<int>(v) << std::endl;
//	//	std::cout << std::get<0>(v) << std::endl;
//	//	std::cout << std::get<double>(v) << std::endl; // 抛出异常
//	//}
//	//catch (const std::bad_variant_access& e) {
//	//	std::cout << "Error: " << e.what() << std::endl;
//	//}
//
//	//using Value = std::variant<int, double, std::string>;
//	//std::vector<Value> vec = {1, 2, 2.2, "hello", 3.3};
//	//for (auto& e : vec)
//	//{
//	//	// 使用std::get_if尝试获取值
//	//	if (auto pval = std::get_if<int>(&e)) {
//	//		*pval += 10;  // 修改
//	//	}
//	//}
//
//	//// 效率不行，O(N*M) M是类型个数
//	//for (auto& e : vec)
//	//{
//	//	// 使用std::get_if尝试获取值
//	//	if (auto pval = std::get_if<int>(&e)) {
//	//		std::cout << "int value: " << *pval << std::endl;
//	//	}
//	//	else if (auto pval = std::get_if<double>(&e)) {
//	//		std::cout << "double value: " << *pval << std::endl;
//	//	}
//	//	else if (auto pval = std::get_if<std::string>(&e)) {
//	//		std::cout << "string value: " << *pval << std::endl;
//	//	}
//	//}
//	//std::cout << std::endl;
//
//	return 0;
//}

// helper type for the visitor #4
//template<class... Ts>
//struct overloaded : Ts... { using Ts::operator()...; };
//// explicit deduction guide (not needed as of C++20)
//
//template<class... Ts>
//overloaded(Ts...)->overloaded<Ts...>;
//
//int main()
//{
//	using Value = std::variant<int, double, std::string>;
//	std::vector<Value> vec = {1, 2, 2.2, "hello", 3.3};
//
//	/*for (auto& e : vec)
//	{
//		std::visit([](auto& x) { x++; }, e);
//	}
//	std::cout << '\n';*/
//
//	struct VisitorOP {
//		void operator()(int& i) const {
//			//std::cout << "int: " << i << '\n';
//			i += 1;
//		}
//		void operator()(double& d) const {
//			//std::cout << "double: " << d << '\n';
//			d += 2.2;
//		}
//		void operator()(std::string& s) const {
//			//std::cout << "string: " << s << '\n';
//			s += '%';
//		}
//	};
//
//	// 修改
//	for (auto& e : vec)
//	{
//		std::visit(VisitorOP(), e);
//	}
//	std::cout << '\n';
//
//	for (auto& e : vec)
//	{
//		std::visit([](auto&& x) {std::cout << x << " "; }, e);
//	}
//	std::cout << '\n';
//
//	for (auto& e : vec)
//	{
//
//		// 2. value-returning visitor, demonstrates the idiom of returning another variant
//		Value w = std::visit([](auto&& arg) -> Value { return arg + arg; }, e);
//
//		// 3. type-matching visitor: a lambda that handles each type differently
//		std::cout << ". After doubling, variant holds ";
//		std::visit([](auto&& arg)
//			{
//				using T = std::decay_t<decltype(arg)>;
//				if constexpr (std::is_same_v<T, int>)
//					std::cout << "int with value " << arg << '\n';
//				else if constexpr (std::is_same_v<T, double>)
//					std::cout << "double with value " << arg << '\n';
//				else if constexpr (std::is_same_v<T, std::string>)
//					std::cout << "std::string with value " << arg << '\n';
//				else
//					static_assert(false, "non-exhaustive visitor!");
//			}, w);
//	}
//
//	for (auto& v : vec)
//	{
//		// 4. another type-matching visitor: a class with 3 overloaded operator()'s
//		std::visit(overloaded{
//			[](int arg) { std::cout << arg << ' '; },
//			[](double arg) { std::cout << arg << ' '; },
//			[](const std::string& arg) { std::cout << arg << ' '; }
//			}, v);
//	}
//}

//struct S
//{
//	S(int i) : i(i) {}
//	int i;
//};
//
//int main()
//{
//	std::variant<int, int> v1;
//	//v1 = 1;
//	v1.emplace<0>(1);
//	std::cout << std::get<0>(v1) << std::endl;
//
//	std::variant<std::monostate, S, int> v2;
//
//
//	return 0;
//}

//// helper type for the visitor #4
//template<class... Ts>
//struct overloaded : Ts... { using Ts::operator()...; };
//// explicit deduction guide (not needed as of C++20)
//
//template<class... Ts>
//overloaded(Ts...)->overloaded<Ts...>;
//
//template<class K, size_t Len = 8>
//class HashTable
//{
//	using Value = std::variant<std::list<K>, std::set<K>>;
//public:
//	HashTable()
//		:_tables(10)
//	{}
//
//	void Insert(const K& key)
//	{
//		// 扩容
//		size_t hashi = key % _tables.size();
//
//		auto listInsert = [this, &key, hashi](std::list<K>& lt)
//		{
//			// 小于8，则插入到链表
//			if (lt.size() < Len)
//			{
//				lt.push_back(key);
//			}
//			else
//			{
//				// 大于8，则转换插入到红黑树(set)
//				std::set<K> s(lt.begin(), lt.end());
//				s.insert(key);
//
//				_tables[hashi] = move(s);
//			}
//		};
//
//		auto setInsert = [&key](std::set<K>& s)
//		{
//			s.insert(key);
//		};
//
//		std::visit(overloaded(
//			listInsert,
//			setInsert
//		), _tables[hashi]);
//	}
//
//	bool Find(const K& key)
//	{
//		size_t hashi = key % _tables.size();
//
//		// 链表查找
//		auto listFind = [&key](std::list<K>& lt)
//		{
//			return std::find(lt.begin(), lt.end(), key) != lt.end();
//		};
//
//		// 红黑树查找
//		auto setFind = [&key](std::set<K>& s)
//		{
//			return s.count(key) != 0;
//		};
//
//		return std::visit(overloaded(
//			listFind,
//			setFind
//		), _tables[hashi]);
//	}
//
//private:
//	std::vector<Value> _tables;
//};
//

#include <any>
#include <string>
#include <iostream>
#include <assert.h>
//
//int main() {
//	std::any a1 = 42; // 存放 int
//	std::any a2 = 3.14; // 存放 double
//	std::any a3 = std::string("Hello"); // 存放 std::string
//
//	a1 = 100000000;
//	a3 = 22;
//
//	std::cout << sizeof(a1) << '\n';
//	std::cout << sizeof(a3) << '\n';
//
//	std::any a4;
//	a4 = std::pair<std::string, std::string>("xxxx", "yyyy");
//
//	a3.emplace<std::string>("%%%%%%%");
//	std::cout << any_cast<std::string>(a3) << '\n';
//
//	a3.emplace<std::string>(10, 'x');
//	std::cout << any_cast<std::string>(a3) << '\n';
//
//	// 检查是否有值
//	if (a3.has_value()) {
//		std::cout << "a has value" << std::endl;
//		// 获取类型信息
//		const std::type_info& ti = a3.type();
//		std::cout << "a type: " << ti.name() << std::endl;
//
//		std::cout << typeid(std::string).name() << '\n';
//	}
//
//	return 0;
//}

// vector中存储any类型
//void anyVector() {
//	std::string str("hello world");
//	std::vector<std::any> v = { 1.1, 2, str };
//
//	//遍历效率 O(N*M) M是存储类型个数
//	/*for (const auto& item : v) {
//		if (item.type() == typeid(int)) {
//			std::cout << "整数配置: " << std::any_cast<int>(item) << '\n';
//		}
//		else if (item.type() == typeid(double)) {
//			std::cout << "浮点配置: " << std::any_cast<double>(item) << '\n';
//		}
//		else if (item.type() == typeid(std::string)) {
//			std::cout << "字符串配置: " << std::any_cast<std::string>(item) <<'\n';
//		}
//		else
//		{
//			assert(false);
//		}
//	}*/
//
//	for (const auto& item : v) {
//		if (auto ptr = std::any_cast<int>(&item)) {
//			std::cout << "整数配置: " << *ptr << '\n';
//		}
//		else if (auto ptr = std::any_cast<double>(&item)) {
//			std::cout << "浮点配置: " << *ptr << '\n';
//		}
//		else if (auto ptr = std::any_cast<std::string>(&item)) {
//			std::cout << "字符串配置: " << *ptr << '\n';
//		}
//		else
//		{
//			assert(false);
//		}
//	}
//}
//
//int main() {
//	std::any a1 = 42; // 存放 int
//	std::any a2 = 3.14; // 存放 double
//	std::any a3 = std::string("Hello"); // 存放 std::string
//
//	// 方式一：转换为值的类型（如果类型不匹配，抛出 std::bad_any_cast）
//	try {
//		int int_value = std::any_cast<int>(a1); // 正确，a1 存放的是 int
//		std::cout << "Value: " << int_value << '\n';
//		double double_value = std::any_cast<double>(a1); // 错误！抛出异常
//	}
//	catch (const std::bad_any_cast& e) {
//		std::cout << "Cast failed: " << e.what() << '\n';
//	}
//
//	// 方式二：转换为值和转换为值的引用
//	// 这里any_cast返回的是a3存储对象的拷贝，要尽量避免这样使用
//	// 小心，拷贝
//	std::string str_ref1 = std::any_cast<std::string>(a3);
//	str_ref1[0]++;
//	std::cout << std::any_cast<std::string>(a3) << '\n';
//
//	// 推荐，引用
//	//std::string& str_ref2 = std::any_cast<std::string&>(a3);
//	auto& str_ref2 = std::any_cast<std::string&>(a3);
//	str_ref2[0]++;
//	std::cout << std::any_cast<const std::string&>(a3) << '\n';
//
//	std::string&& str_ref3 = std::any_cast<std::string&&>(move(a3));
//	str_ref3[0]++;
//	std::cout << std::any_cast<std::string&>(a3) << '\n';
//
//	// 移动构造
//	//std::string str_ref4 = std::any_cast<std::string&&>(move(a3));
//	auto str_ref4 = std::any_cast<std::string&&>(move(a3));
//	str_ref4[0]++;
//	std::cout << std::any_cast<std::string&>(a3) << '\n';
//
//	//a1.reset();
//	// 方式三：转换为指针（如果类型不匹配，返回 nullptr，不会抛出异常）
//	if (auto ptr = std::any_cast<int>(&a1)) { // 传递指针，返回指针
//		std::cout << "Value via pointer: " << *ptr << '\n';
//	}
//	else {
//		std::cout << "Not an int or is empty.\n";
//	}
//
//	anyVector();
//}


//template<class K, size_t Len = 8>
//class HashTable
//{
//public:
//	HashTable()
//		:_tables(10, std::list<K>())
//	{}
//
//	void Insert(const K& key)
//	{
//		// 扩容
//		size_t hashi = key % _tables.size();
//
//		auto listInsert = [this, &key, hashi](std::list<K>& lt)
//		{
//			// 小于8，则插入到链表
//			if (lt.size() < Len)
//			{
//				lt.push_back(key);
//			}
//			else
//			{
//				// 大于8，则转换插入到红黑树(set)
//				std::set<K> s(lt.begin(), lt.end());
//				s.insert(key);
//
//				_tables[hashi] = move(s);
//			}
//		};
//
//		auto setInsert = [&key](std::set<K>& s)
//		{
//			s.insert(key);
//		};
//
//		if (auto ptr = any_cast<std::list<K>>(&_tables[hashi]))
//		{
//			listInsert(*ptr);
//		}
//		else if (auto ptr = any_cast<std::set<K>>(&_tables[hashi]))
//		{
//			setInsert(*ptr);
//		}
//		else
//		{
//			assert(false);
//		}
//	}
//
//	bool Find(const K& key)
//	{
//		size_t hashi = key % _tables.size();
//		// 链表查找
//		auto listFind = [&key](std::list<K>& lt)
//		{
//			return std::find(lt.begin(), lt.end(), key) != lt.end();
//		};
//
//		// 红黑树查找
//		auto setFind = [&key](std::set<K>& s)
//		{
//			return s.count(key) != 0;
//		};
//
//
//		if (auto ptr = any_cast<std::list<K>>(&_tables[hashi]))
//		{
//			return listFind(*ptr);
//		}
//		else if (auto ptr = any_cast<std::set<K>>(&_tables[hashi]))
//		{
//			return setFind(*ptr);
//		}
//		else
//		{
//			assert(false);
//			return false;
//		}
//	}
//
//private:
//	std::vector<std::any> _tables;
//};
//
//int main()
//{
//	HashTable<int> ht;
//	for (size_t i = 0; i < 10; i++)
//	{
//		ht.Insert(i * 10 + 5);
//	}
//
//	std::cout << ht.Find(15) << std::endl;
//	std::cout << ht.Find(3) << std::endl;
//
//	return 0;
//}

// 常规使用，定义访问
//#include <iostream>
//#include <string>
//#include <string_view>
//
//void print(std::string_view sv) {
//	std::cout << "String view: " << sv << "\n";
//	std::cout << "Length: " << sv.size() << "\n";
//
//	for (size_t i = 0; i < sv.size(); ++i)
//	{
//		// sv[i]++;
//		std::cout << sv[i] << " ";
//	}
//	std::cout << "\n";
//
//	for (auto& ch : sv)
//	{
//		// ch++;
//		std::cout << ch << " ";
//	}
//	std::cout << "\n";
//}
//
//int main()
//{
//	std::string_view sv0;
//	print(sv0);
//
//	// 从C风格字符串构造
//	//std::string_view sv1("Hello, world!");
//	std::string_view sv1("Hello", 6);
//	print(sv1);
//
//	//std::string_view sv2("Hello, world!", 5);
//
//	// 从std::string构造
//	std::string str = "C++17 string_view";
//	std::string_view sv2(str);
//	print(sv2);
//
//	sv2.remove_prefix(6);
//	print(sv2);
//
//
//	// 从部分字符串构造
//	std::string_view sv3(str.c_str() + 6, 6);
//	print(sv3);
//
//	return 0;
//}

// string_view和strings字符串传参性能对比测试
//#include <iostream>
//#include <chrono>
//#include <string>
//#include <string_view>
//// 使用std::string参数
//void process_string(const std::string& s) {
//}
//// 使用std::string_view参数
//void process_string_view(std::string_view sv) {
//}
//
//int main() {
//	const int N = 100'0000;
//	std::string long_str = "This is a very long string...";
//
//	// 测试std::string参数
//	auto start1 = std::chrono::high_resolution_clock::now();
//	for (int i = 0; i < N; ++i) {
//		process_string(long_str); // 无额外开销
//		process_string("literal"); // 创建临时string
//	}
//	auto end1 = std::chrono::high_resolution_clock::now();
//
//	// 测试std::string_view参数
//	auto start2 = std::chrono::high_resolution_clock::now();
//	for (int i = 0; i < N; ++i) {
//		process_string_view(long_str); // 隐式转换
//		process_string_view("literal"); // 无临时对象
//	}
//	auto end2 = std::chrono::high_resolution_clock::now();
//
//	auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start1);
//	auto duration2 = std::chrono::duration_cast<std::chrono::milliseconds>(end2 - start2);
//
//	std::cout << "std::string: " << duration1.count() << "ms\n";
//	std::cout << "std::string_view: " << duration2.count() << "ms\n";
//
//	return 0;
//}

//std::string_view extract_str(std::string_view input, char delimiter) {
//	size_t pos = input.find(delimiter);
//	return input.substr(0, pos);
//}
//
//// 继续切分字符串
//std::vector<std::string_view> split(std::string_view str, char delimiter) {
//	std::vector<std::string_view> result;
//	size_t start = 0;
//	size_t end = str.find(delimiter);
//	while (end != std::string_view::npos) {
//		result.push_back(str.substr(start, end - start));
//		start = end + 1;
//		end = str.find(delimiter, start);
//	}
//	result.push_back(str.substr(start));
//
//	return result;
//}
//
//int main()
//{
//	const char* str = "https://chat.deepseek.com/a/chat/s/4ae60e97-d7b0-4542-aadd-5f82d76e74e7";
//	std::string_view sv = extract_str(str, ':');
//	std::cout << sv << std::endl;
//
//	auto v = split(str + 9, '/');
//	for (auto e : v)
//	{
//		std::cout << e << std::endl;
//	}
//	std::cout << std::endl;
//
//	/*constexpr std::string_view sv1("https://chat.deepseek.com/a/chat/s/4ae60e97-d7b0-4542-aadd-5f82d76e74e7");
//	constexpr auto pos1 = sv1.find(":");
//	std::cout << pos1<< std::endl;*/
//
//	return 0;
//}

//std::string_view get_view() {
//	std::string temp = "Temporary string";
//	return temp; // 严重错误！temp将被销毁
//}
//
//void error_example1() {
//	std::string_view sv = get_view(); // sv现在指向已释放的内存
//	std::cout << sv << std::endl; // 未定义行为
//}
//
//void error_example2()
//{
//	char buffer[] = { 'T', 'e', 's', 't', '.', 't', 'x', 't', '\0'}; // 不是空终止的
//	std::string_view sv(buffer, 4); // 正确指定长度
//	std::cout << sv << std::endl;
//
//	std::string_view filename(buffer, 9);
//	FILE* fout = fopen(filename.data(), "w");
//	if (fout != NULL)
//	{
//		fputs("fopen example", fout);
//		fclose(fout);
//	}
//	else
//	{
//		perror("fopen fail");
//	}
//}
//
//void error_example3()
//{
//	std::string str = "Hello";
//	std::string_view sv = str;
//
//	// 修改原始字符串会使string_view失效
//	str[0] = 'h'; // 合法，sv仍然有效
//	std::cout << sv << std::endl;
//
//	str = "New value 111111111111111111111111"; // 可能导致重新分配，使sv失效
//	std::cout << sv << std::endl;
//}
//
//int main()
//{
//	error_example1();
//	error_example2();
//	error_example3();
//
//	return 0;
//}

#include <filesystem>
#include <fstream>

// 使用命名空间别名 fs 来简化代码（非常常见的做法）
namespace fs = std::filesystem;

//int main()
//{
//	//fs::path p1 = "/usr/local/bin"; // 从字符串隐式构造
//	fs::path p2 = "C:\\Windows\\System32"; // Windows 路径，注意转义反斜杠
//	fs::path p3 = R"(C:\Windows\System32)"; // 使用原始字符串字面量避免转义
//	fs::path p4 = fs::current_path(); // 获取当前工作目录的路径
//
//	std::cout << p2 << '\n';
//	std::cout << p3 << '\n';
//	std::cout << p4 << '\n';
//
//	fs::path p = R"(C:\Windows\System32\test.cpp)"; // 使用原始字符串字面量避免转义
//	std::cout << p << std::endl;
//	std::cout << p.root_name() << std::endl; // 根名称 (如 "C:")（在POSIX上通常为空）
//	std::cout << p.root_directory() << std::endl; // 根目录 (如 "\\") （在POSIX上通常为 / ）
//	std::cout << p.root_path() << std::endl; // 根路径 (如 "C:\\")（在POSIX上通常为 / ）
//	std::cout << p.relative_path() << std::endl; // 相对路径部分
//	std::cout << p.parent_path() << std::endl; // 父路径
//	std::cout << p.filename() << std::endl; // 文件名部分
//	std::cout << p.stem() << std::endl; // 不带扩展名的文件名
//	std::cout << p.extension() << std::endl; // 扩展名
//
//	return 0;
//}

//int main()
//{
//	//fs::path p = "temp";
//	//// 使用 /= 运算符追加路径，自动处理分隔符
//	//// p 现在为 "temp/subdir/file.log" (POSIX) 或 "temp\\subdir\\file.log" (Windows)
//	//p /= "subdir";
//	//p /= "file.log";
//	//std::cout << p << std::endl;
//
//	////p += "test.cpp";
//	////std::cout << p << std::endl;
//
//	//// 替换最后的文件名部分
//	//// p 现在为 "temp/subdir/data.json"
//	//p.replace_filename("data.json");
//	//std::cout << p << std::endl;
//
//	//// 移除最后的文件名部分
//	//// p 现在为 "temp/subdir/"
//	//p.remove_filename();
//	//std::cout << p << std::endl;
//
//	fs::path p = R"(C:\Users\Public\Documents)";
//	// 检查是绝对路径还是相对路径
//	if (p.is_absolute())
//		std::cout << "is_absolute" << '\n';
//	if (p.is_relative())
//		std::cout << "is_relative" << '\n';
//
//	// 有没有条目名称和根路径
//	if (p.has_filename())
//		std::cout << "has_filename" << '\n';
//	if (p.has_root_path())
//		std::cout << "has_root_path" << '\n';
//
//	// 路径转换为字符串
//	std::string str = p.string(); // 转换为平台依赖的字符串格式
//	std::wstring wstr = p.wstring(); // 转换为宽字符版本
//	std::u8string u8str = p.u8string(); // 转换为UTF8版本
//
//	return 0;
//}

//int main()
//{
//	fs::path p = "Test.cpp";
//
//	// 检查文件是否存在
//	if (fs::exists(p)) {
//		std::cout << "File exists!\n";
//		// 检查它是普通文件还是目录
//		if (fs::is_regular_file(p)) {
//			std::cout << "It's a regular file.\n";
//			std::cout << "File size: " << fs::file_size(p) << " bytes\n";
//		}
//		else if (fs::is_directory(p)) {
//			std::cout << "It's a directory.\n";
//		}
//
//		// 获取最后修改时间
//		auto ftime = fs::last_write_time(p);
//
//		using namespace std::chrono_literals;
//
//		// 修改文件的最后修改时间到1小时以后
//		fs::last_write_time(p, ftime + 1h);
//	}
//
//	return 0;
//}
//
//void demo_perms(std::filesystem::perms p)
//{
//    using std::filesystem::perms;
//    auto show = [=](char op, perms perm)
//    {
//        std::cout << (perms::none == (perm & p) ? '-' : op);
//    };
//    show('r', perms::owner_read);
//    show('w', perms::owner_write);
//    show('x', perms::owner_exec);
//    show('r', perms::group_read);
//    show('w', perms::group_write);
//    show('x', perms::group_exec);
//    show('r', perms::others_read);
//    show('w', perms::others_write);
//    show('x', perms::others_exec);
//    std::cout << '\n';
//}
//
//int main()
//{
//    try
//    {
//        fs::path file_path = "test.txt";
//        std::ofstream(file_path) << "hello";
//
//        demo_perms(fs::status(file_path).permissions());
//
//        // 方法一：直接替换权限
//        // 这将文件的权限直接设置为 (rw-r--r--)
//        fs::permissions(file_path,
//            fs::perms::owner_read | fs::perms::owner_write |
//            fs::perms::group_read |
//            fs::perms::others_read,
//            fs::perm_options::replace); // <-- 关键选项：替换
//        demo_perms(fs::status(file_path).permissions());
//
//        // 方法二：添加权限
//        // 为用户组添加写权限
//        fs::permissions(file_path,
//            fs::perms::group_write,
//            fs::perm_options::add); // <-- 关键选项：添加
//        demo_perms(fs::status(file_path).permissions());
//
//        // 方法三：移除权限
//        // 移除其他用户的读权限
//        fs::permissions(file_path,
//            fs::perms::others_read,
//            fs::perm_options::remove); // <-- 关键选项：移除
//        demo_perms(fs::status(file_path).permissions());
//    }
//    catch (const std::exception& e)
//    {
//        std::cout << e.what() << '\n';
//    }
//
//    getchar();
//
//    return 0;
//}

//int main()
//{
//	try
//	{
//		fs::path p1 = fs::current_path() / "Test.cpp";
//		std::cout << fs::exists(p1) << std::endl; // 文件是否存在
//		std::cout << fs::file_size(p1) << std::endl; // 文件大小
//
//		//fs::path p2 = "xx"; // 相对路径
//		fs::path p2 = fs::current_path() / "xx"; // 绝对路径
//		// 创建目录如果目录存在不会报错
//		// 创建单层目录，如果是多层，则会抛异常
//		fs::create_directory(p2); // 创建目录
//
//		// 创建多层目录
//		fs::path p3 = p2 / R"(1\2\3)";
//		fs::create_directories(p3); // 递归创建目录
//
//		// copy_file复制文件内容到一个新文件，默认情况下文件存在会报错
//		// 需要使用待选项的控制
//		fs::path p4 = p2 / "inset.cpp";
//		std::ofstream{ p4 };
//
//		//fs::copy_file(p1, p4); // 抛异常
//		fs::copy_file(p1, p4, fs::copy_options::overwrite_existing);
//
//		// 复制目录 -- 默认行为（仅复制文件，不递归目录，不覆盖现有文件）
//		//fs::copy(p2, "xx_copy");
//
//		// 递归复制所有文件和子目录
//		fs::copy(p2, "xx_copy", fs::copy_options::recursive |
//			fs::copy_options::overwrite_existing);
//
//		// 重命名文件 inset.cpp为xx.cpp
//		//fs::rename(p4, p2 / "xx.cpp");
//
//		// 移动文件，从xx下面移动到当前目录下面
//		//fs::rename(p2 / "xx.cpp", "xx.cpp");
//
//		// 如果没有这个目录也不会报错
//		// 非空目录报错
//		fs::remove(p3);
//
//		// 删除文件或空目录
//		fs::remove_all(fs::current_path() / "xx_copy"); // 递归删除所有内容
//		//fs::remove_all(fs::current_path() / "xx_copy");
//	}
//	catch (const std::exception& e)
//	{
//		std::cout << e.what() << '\n';
//	}
//
//	return 0;
//}

//int main()
//{
//	try
//	{
//		//fs::path p1 = fs::current_path();
//		fs::path p1 = R"(C:\Windows)";
//
//
//		// 范围for实现，非递归遍历，只遍历读取当前目录下的内容
//		/*for (const auto& entry : fs::directory_iterator(p1)) {
//			std::cout << " " << entry.path().filename() << " - "
//				<< (entry.is_directory() ? "目录" : "文件") << "\n";
//		}
//		std::cout << '\n';*/
//
//		// 范围for实现，非递归遍历，只遍历读取当前目录下的内容
//		for (const auto& entry : fs::recursive_directory_iterator(p1, fs::directory_options::skip_permission_denied)) {
//			std::cout << " " << entry.path().filename() << " - "
//				<< (entry.is_directory() ? "目录" : "文件") << "\n";
//		}
//		std::cout << '\n';
//
//		// 直接使用迭代器实现遍历，下面的范围for本质是转换为这个访问
//		//auto dit = fs::recursive_directory_iterator(p1);
//		//auto it = begin(dit);
//		//while (it != end(dit)) {
//		//	//const fs::directory_entry& entry = *it;
//		//	std::cout << " " << it->path().filename() << " - "
//		//	<< (it->is_directory() ? "目录" : "文件") << "\n";
//		//	++it;
//		//}
//		//std::cout << '\n';
//
//		//auto it = fs::recursive_directory_iterator(p1);
//		//fs::recursive_directory_iterator end;
//		//while (it != end) {
//		//	//const fs::directory_entry& entry = *it;
//		//	std::cout << " " << it->path().filename() << " - "
//		//		<< (it->is_directory() ? "目录" : "文件") << "\n";
//		//	++it;
//		//}
//		//std::cout << '\n';
//	}
//	catch (const std::exception& e)
//	{
//		std::cout << e.what() << '\n';
//	}
//
//	return 0;
//}

//int main()
//{
//	// 异常的方式
//	try {
//		fs::path p = "nonexistent.txt";
//		auto size = fs::file_size(p); // 可能抛出异常
//		std::cout << "文件大小: " << size << std::endl;
//	}
//	catch (const fs::filesystem_error& ex) {
//		std::cout
//			<< "what(): " << ex.what() << '\n'
//			<< "path1(): " << ex.path1() << '\n'
//			<< "path2(): " << ex.path2() << '\n';
//	}
//
//	// 错误码方式
//	std::error_code ec;
//	fs::path p = "nonexistent.txt";
//	auto size = fs::file_size(p, ec);
//	if (ec) {
//		std::cout << "错误代码: " << ec.value() << std::endl;
//		std::cout << "错误信息: " << ec.message() << std::endl;
//		std::cout << "错误类别: " << ec.category().name() << std::endl;
//	}
//	else {
//		std::cout << "文件大小: " << size << std::endl;
//	}
//
//	return 0;
//}